#pragma once

#include <QtCore/QtGlobal>
#include <QObject>
#include <QMap>
#include <QSet>
#include <QPixmap>
#include <QMutex>
#include <QWaitCondition>
#include <QFutureSynchronizer>
#include <QThread>
#include "thumbnailengine.h"
#include "mediaitem.h"

class IconCache : public QObject
{
    Q_OBJECT
public:
    IconCache(QObject *parent = 0);
    virtual ~IconCache();
    QSharedPointer<QPixmap> load(const MediaItemPtr & item, const QSize & size);
    QSharedPointer<QPixmap> load(const QString & filename, const QSize & size);
    ThumbnailEngine & engine() { return m_engine; }
    int queueSize();

signals:
    void loaded(MediaItemPtr item, QSize size, QSharedPointer<QPixmap> icon);

public slots:
    void enqueue(const MediaItemPtr & item, const QSize & size);

private:
    void run(bool highpriority);
    void addRoundCorners(QImage & img, int radius);

    struct QueueItem {
        bool operator==(const QueueItem & other)
        {
            return other.item != item || other.filename != filename || other.size != size;
        }

        MediaItemPtr item;
        QString filename;
        QSize size;
    };

    QList<QueueItem> m_queue;
    QSet<QPair<MediaItemPtr, QSize> > m_queueset;
    QList<QSharedPointer<QPixmap> > m_cache;

    QMutex m_mutex;
    QWaitCondition m_cond;
    bool m_quit;
    ThumbnailEngine m_engine;

    class Worker : public QThread
    {
    public:
        Worker(IconCache * cache, bool highpriority);
    protected:
        virtual void run();
    private:
        IconCache * m_cache;
        bool m_highpriority;
    };

    QList<Worker*> m_threads;
};
